package com.opensource.svgaplayer;

import com.opensource.svgaplayer.bitmap.SVGABitmapByteArrayDecoder;
import ohos.agp.components.StackLayout;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;

/**
 * ex.
 *
 * @author wl
 * @since 2021-06-28
 */
public class SVGADynamicEntity {
    private HashMap<String, Boolean> dynamicHidden = new HashMap<>();
    private HashMap<String, PixelMap> dynamicImage = new HashMap<>();
    private HashMap<String, IClickAreaListener> dynamicIClickArea = new HashMap<>();

    public HashMap<String, String> getDynamicText() {
        return dynamicText;
    }

    private HashMap<String, StackLayout> dynamicStaticLayoutText = new HashMap<>();
    private HashMap<String, DynamicDrawLisenter> dynamicDrawer = new HashMap();
    private HashMap<String, String> dynamicText = new HashMap<>();
    private HashMap<String, StackLayout> dynamicBoringLayoutText = new HashMap<>();
    private HashMap<String, int[]> mClickMap = new HashMap<>();
    private HashMap<String, DynamicDrawSizeLisenter> dynamicDrawerSized = new HashMap();
    private boolean isTextDirty = false;

    /**
     * setDynamicText
     *
     * @param dynamicText HashMap<String, String>
     */
    public void setDynamicText(HashMap<String, String> dynamicText) {
        this.dynamicText = dynamicText;
    }

    /**
     * getDynamicTextPaint
     *
     * @return HashMap<String, Paint>
     */
    public HashMap<String, Paint> getDynamicTextPaint() {
        return dynamicTextPaint;
    }

    /**
     * setDynamicTextPaint
     *
     * @param dynamicTextPaint HashMap<String, Paint>
     */
    public void setDynamicTextPaint(HashMap<String, Paint> dynamicTextPaint) {
        this.dynamicTextPaint = dynamicTextPaint;
    }

    private HashMap<String, Paint> dynamicTextPaint = new HashMap<>();

    /**
     * getDynamicStaticLayoutText
     *
     * @return HashMap<String, StackLayout>
     */
    public HashMap<String, StackLayout> getDynamicStaticLayoutText() {
        return dynamicStaticLayoutText;
    }

    /**
     * getmClickMap
     *
     * @return HashMap<String, int [ ]>
     */
    public HashMap<String, int[]> getmClickMap() {
        return mClickMap;
    }

    /**
     * setmClickMap
     *
     * @param mClickMap HashMap<String, int[]>
     */
    public void setmClickMap(HashMap<String, int[]> mClickMap) {
        this.mClickMap = mClickMap;
    }

    /**
     * setDynamicStaticLayoutText
     *
     * @param dynamicStaticLayoutText HashMap<String, StackLayout>
     */
    public void setDynamicStaticLayoutText(HashMap<String, StackLayout> dynamicStaticLayoutText) {
        this.dynamicStaticLayoutText = dynamicStaticLayoutText;
    }

    /**
     * getDynamicBoringLayoutText
     *
     * @return HashMap<String, StackLayout>
     */
    public HashMap<String, StackLayout> getDynamicBoringLayoutText() {
        return dynamicBoringLayoutText;
    }

    /**
     * setDynamicBoringLayoutText
     *
     * @param dynamicBoringLayoutText HashMap<String, StackLayout>
     */
    public void setDynamicBoringLayoutText(HashMap<String, StackLayout> dynamicBoringLayoutText) {
        this.dynamicBoringLayoutText = dynamicBoringLayoutText;
    }

    /**
     * getDynamicIClickArea
     *
     * @return HashMap<String, IClickAreaListener>
     */
    public HashMap<String, IClickAreaListener> getDynamicIClickArea() {
        return dynamicIClickArea;
    }

    /**
     * getDynamicDrawer
     *
     * @return HashMap<String, DynamicDrawLisenter>
     */
    public HashMap<String, DynamicDrawLisenter> getDynamicDrawer() {
        return dynamicDrawer;
    }

    /**
     * getDynamicDrawerSized
     *
     * @return HashMap<String, DynamicDrawSizeLisenter>
     */
    public HashMap<String, DynamicDrawSizeLisenter> getDynamicDrawerSized() {
        return dynamicDrawerSized;
    }

    /**
     * setTextDirty
     *
     * @param textDirty boolean
     */
    public void setTextDirty(boolean textDirty) {
        isTextDirty = textDirty;
    }

    /**
     * setHidden
     *
     * @param value  Boolean
     * @param forKey String
     */
    public void setHidden(Boolean value, String forKey) {
        this.dynamicHidden.put(forKey, value);
    }

    /**
     * setDynamicImage
     *
     * @param bitmap PixelMap
     * @param forKey String
     */
    public void setDynamicImage(PixelMap bitmap, String forKey) {
        this.dynamicImage.put(forKey, bitmap);
    }

    /**
     * setDynamicImage
     *
     * @param url    String
     * @param forKey String
     */
    public void setDynamicImage(String url, String forKey) {
        EventHandler handler = new EventHandler(EventRunner.getMainEventRunner());
        SVGAParser.getThreadPoolExecutor().execute(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connect = null;
                try {
                    URL ur = new URL(url);
                    connect = (HttpURLConnection) ur.openConnection();
                    connect.setConnectTimeout(20 * 1000);
                    connect.setRequestMethod("GET");
                    connect.connect();
                    InputStream stream = connect.getInputStream();
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    byte[] buffer = new byte[4096];
                    while (true) {
                        int count = stream.read(buffer, 0, 4096);
                        if (count == -1) {
                            break;
                        }
                        outputStream.write(buffer, 0, count);
                    }
                    PixelMap bitmap = SVGABitmapByteArrayDecoder.getInstance().onDecode(outputStream.toByteArray(), new ImageSource.DecodingOptions());
                    handler.postTask(new Runnable() {
                        @Override
                        public void run() {
                            setDynamicImage(bitmap, forKey);
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        connect.disconnect();
                    } catch (Throwable disconnectException) {
                        // ignored here
                    }
                }
            }
        });
    }

    /**
     * setDynamicText
     *
     * @param text      String
     * @param textPaint Paint
     * @param forKey    String
     */
    public void setDynamicText(String text, Paint textPaint, String forKey) {
        this.isTextDirty = true;
        this.dynamicText.put(forKey, text);
        this.dynamicTextPaint.put(forKey, textPaint);
    }

    /**
     * setDynamicDrawer
     *
     * @param lisenter DynamicDrawLisenter
     * @param forKey   String
     */
    public void setDynamicDrawer(DynamicDrawLisenter lisenter, String forKey) {
        this.dynamicDrawer.put(forKey, lisenter);
    }

    public interface DynamicDrawLisenter {
        boolean invoke(Canvas canvas, int index);
    }

    public interface DynamicDrawSizeLisenter {
        boolean invoke(Canvas canvas, int index, int width, int height);
    }

    /**
     * setClickArea
     *
     * @param clickKey List<String>
     */
    public void setClickArea(List<String> clickKey) {
        for (String itemKey : clickKey) {
            dynamicIClickArea.put(itemKey, new IClickAreaListener() {
                @Override
                public void onResponseArea(String key, int x0, int y0, int x1, int y1) {
                    if (mClickMap.get(key) == null) {
                        int[] i = new int[]{x0, y0, x1, y1};
                        mClickMap.put(key, i);
                    } else {
                        int[] i = mClickMap.get(key);
                        i[0] = x0;
                        i[1] = y0;
                        i[2] = x1;
                        i[3] = y1;
                    }
                }
            });
        }
    }

    /**
     * setClickArea
     *
     * @param clickKey String
     */
    public void setClickArea(String clickKey) {
        dynamicIClickArea.put(clickKey, new IClickAreaListener() {
            @Override
            public void onResponseArea(String key, int x0, int y0, int x1, int y1) {
                if (mClickMap.get(key) == null) {
                    int[] i = new int[]{x0, y0, x1, y1};
                    mClickMap.put(key, i);
                } else {
                    int[] i = mClickMap.get(key);
                    i[0] = x0;
                    i[1] = y0;
                    i[2] = x1;
                    i[3] = y1;
                }
            }
        });
    }

    /**
     * setDynamicDrawerSized
     *
     * @param lisenter DynamicDrawSizeLisenter
     * @param forKey   String
     */
    public void setDynamicDrawerSized(DynamicDrawSizeLisenter lisenter, String forKey) {
        this.dynamicDrawerSized.put(forKey, lisenter);
    }

    /**
     * clearDynamicObjects
     */
    public void clearDynamicObjects() {
        this.isTextDirty = true;
        this.dynamicHidden.clear();
        this.dynamicImage.clear();
        this.dynamicText.clear();
        this.dynamicTextPaint.clear();
        this.dynamicIClickArea.clear();
        this.mClickMap.clear();
        this.dynamicDrawer.clear();
        this.dynamicDrawerSized.clear();
    }

    /**
     * getDynamicHidden
     *
     * @return HashMap<String, Boolean>
     */
    public HashMap<String, Boolean> getDynamicHidden() {
        return dynamicHidden;
    }

    /**
     * getDynamicImage
     *
     * @return HashMap<String, PixelMap>
     */
    public HashMap<String, PixelMap> getDynamicImage() {
        return dynamicImage;
    }

    /**
     * isTextDirty
     *
     * @return boolean
     */
    public boolean isTextDirty() {
        return isTextDirty;
    }
}